﻿using System;
using System.Collections.Generic;
using System.Linq;

using Whoever.Framework.CustomException;
using Whoever.Patterns.Business;

using EditorialProyectos.Business.Entities;
using EditorialProyectos.Business.Entities.Enum;
using EditorialProyectos.DataAccess.Repositories;

namespace EditorialProyectos.Business
{
    public class ProjectManager : Manager<Project>
    {
        public ProjectManager()
            : base(RepositoryFactory.ProjectRepository)
        {
        }

        public override IEnumerable<Project> GetAll()
        {
            var items = base.GetAll().ToList();

            //Prevent JSON parser error
            foreach (var item in items)
            {
                item.Html = string.Empty;
            }

            return items;
        }

        public IEnumerable<Project> GetByUser(string userId)
        {
            var items = this.Repository.QueryFactory.GetAll().Where(e => e.UserId == userId).ToList();
            var benefitManager = new BenefitManager();
            //Prevent JSON parser error
            foreach (var item in items)
            {
                item.Html = string.Empty;
                item.Benefits = benefitManager.GetByProjectId(item.Id);
            }

            return items;
        }

        public IEnumerable<Project> GetPending(string userId)
        {
            return GetByUser(userId).Where(e => e.State != ProjectState.Approved).ToList();
        }

        public IEnumerable<Project> GetPending()
        {
            return GetAll().Where(e => e.State == ProjectState.Pending).ToList();
        }

        public IEnumerable<Project> GetOnRevision()
        {
            return this.Repository.QueryFactory.GetAll().Where(e => e.State == ProjectState.OnRevision);
        }

        public IEnumerable<Project> GetApproved()
        {
            return this.Repository.QueryFactory.GetAll().Where(e => e.State == ProjectState.Approved);
        }

        public string GetHtml(int id)
        {
            var html = this.Repository.QueryFactory.GetAll().Where(e => e.Id == id).Select(ee => ee.Html).FirstOrDefault();

            return html ?? string.Empty;
        }

        public override int Insert(Project item)
        {
            item.State = ProjectState.Pending;

            return base.Insert(item);
        }

        public override void Update(Project item)
        {
            if (item.State != ProjectState.Pending)
            {
                Repository.UndoChanges(item);
                throw new BusinessException("Project is not pending");
            }

            base.Update(item);
        }

        public void UpdateRevision(Project item, bool isAuthorized)
        {
            if (isAuthorized)
                base.Update(item);
            else
            {
                Repository.UndoChanges(item);
                throw new BusinessException("Not authorized");
            }
        }

        public void SetToOnRevision(Project item)
        {
            if (item.State == ProjectState.OnRevision)
                throw new BusinessException("Project is already on revision");

            item.State = ProjectState.OnRevision;

            base.Update(item);
        }

        public void SetToApproved(Project item)
        {
            if (item.State != ProjectState.OnRevision)
                throw new BusinessException("Project must be on revision");

            item.State = ProjectState.Approved;

            base.Update(item);
        }

        public void BackToPending(Project item)
        {
            if (item.State != ProjectState.OnRevision)
                throw new BusinessException("Project must be on revision");

            item.State = ProjectState.Pending;

            base.Update(item);
        }

        public void BackToOnRevision(Project item)
        {
            if (item.State != ProjectState.Approved)
                throw new BusinessException("Project must be approved");

            item.State = ProjectState.OnRevision;

            base.Update(item);
        }
    }
}
